﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Manul.Interface.TreeNodes;
using Manul.Genetics;
using Manul.Genetics.Genom;
using Manul.Genetics.Character;
using Manul.GenomCreationTest.StringConstants;

namespace Manul.GenomCreationTest
{
    public static class Extensions
    {
        public static void MoveUp(this TreeNode node)
        {
            bool IsSelected = (node.TreeView.SelectedNode == node);
            TreeNode parent = node.Parent;
            TreeView view = node.TreeView;
            if (parent != null)
            {
                int index = parent.Nodes.IndexOf(node);
                if (index > 0)
                {
                    parent.Nodes.RemoveAt(index);
                    parent.Nodes.Insert(index - 1, node);
                }
                if (parent is ObjectTreeNode<GenomDirectory>)
                    (parent as ObjectTreeNode<GenomDirectory>).Obj.Swap(index, index - 1);
                if (parent is ObjectTreeNode<Locus>)
                    (parent as ObjectTreeNode<Locus>).Obj.Swap(index, index - 1);
                if (parent is ObjectTreeNode<CharacterItem>)
                    (parent as ObjectTreeNode<CharacterItem>).Obj.Swap(index, index - 1);
            }
            else if (node.TreeView.Nodes.Contains(node)) //root node
            {
                int index = view.Nodes.IndexOf(node);
                if (index > 0)
                {
                    view.Nodes.RemoveAt(index);
                    view.Nodes.Insert(index - 1, node);
                }
            }
            if (IsSelected)
                node.TreeView.SelectedNode = node;
        }

        public static void MoveDown(this TreeNode node)
        {
            bool IsSelected = (node.TreeView.SelectedNode == node);
            TreeNode parent = node.Parent;
            TreeView view = node.TreeView;
            if (parent != null)
            {
                int index = parent.Nodes.IndexOf(node);
                if (index < parent.Nodes.Count - 1)
                {
                    parent.Nodes.RemoveAt(index);
                    parent.Nodes.Insert(index + 1, node);
                }
                if (parent is ObjectTreeNode<GenomDirectory>)
                    (parent as ObjectTreeNode<GenomDirectory>).Obj.Swap(index, index + 1);
                if (parent is ObjectTreeNode<Locus>)
                    (parent as ObjectTreeNode<Locus>).Obj.Swap(index, index + 1);
                if (parent is ObjectTreeNode<CharacterItem>)
                    (parent as ObjectTreeNode<CharacterItem>).Obj.Swap(index, index + 1);

            }
            else if (view != null && view.Nodes.Contains(node)) //root node
            {
                int index = view.Nodes.IndexOf(node);
                if (index < view.Nodes.Count - 1)
                {
                    view.Nodes.RemoveAt(index);
                    view.Nodes.Insert(index + 1, node);
                }
            }
            if (IsSelected)
                node.TreeView.SelectedNode = node;
        }

        public static void MoveUp(this TreeNode node, SortedStorage storage)
        {
            bool IsSelected = (node.TreeView.SelectedNode == node);
            TreeNode parent = node.Parent;
            TreeView view = node.TreeView;
            if (parent != null)
            {
                int index = parent.Nodes.IndexOf(node);
                if (index > 0)
                {
                    parent.Nodes.RemoveAt(index);
                    parent.Nodes.Insert(index - 1, node);
                }
                if (parent is ObjectTreeNode<GenomDirectory>)
                    (parent as ObjectTreeNode<GenomDirectory>).Obj.Swap(index, index - 1);
                if (parent is ObjectTreeNode<Locus>)
                    (parent as ObjectTreeNode<Locus>).Obj.Swap(index, index - 1);
                if (parent is ObjectTreeNode<CharacterItem>)
                    (parent as ObjectTreeNode<CharacterItem>).Obj.Swap(index, index - 1);
            }
            else if (node.TreeView.Nodes.Contains(node)) //root node
            {
                int index = view.Nodes.IndexOf(node);
                if (index > 0)
                {
                    view.Nodes.RemoveAt(index);
                    view.Nodes.Insert(index - 1, node);
                }
                storage.Swap(index, index - 1);
            }
            if (IsSelected)
                node.TreeView.SelectedNode = node;
        }

        public static void MoveDown(this TreeNode node, SortedStorage storage)
        {
            bool IsSelected = (node.TreeView.SelectedNode == node);
            TreeNode parent = node.Parent;
            TreeView view = node.TreeView;
            if (parent != null)
            {
                int index = parent.Nodes.IndexOf(node);
                if (index < parent.Nodes.Count - 1)
                {
                    parent.Nodes.RemoveAt(index);
                    parent.Nodes.Insert(index + 1, node);
                }
                if (parent is ObjectTreeNode<GenomDirectory>)
                    (parent as ObjectTreeNode<GenomDirectory>).Obj.Swap(index, index + 1);
                if (parent is ObjectTreeNode<Locus>)
                    (parent as ObjectTreeNode<Locus>).Obj.Swap(index, index + 1);
                if (parent is ObjectTreeNode<CharacterItem>)
                    (parent as ObjectTreeNode<CharacterItem>).Obj.Swap(index, index + 1);

            }
            else if (view != null && view.Nodes.Contains(node)) //root node
            {
                int index = view.Nodes.IndexOf(node);
                if (index < view.Nodes.Count - 1)
                {
                    view.Nodes.RemoveAt(index);
                    view.Nodes.Insert(index + 1, node);
                }
                storage.Swap(index, index + 1);
            }
            if (IsSelected)
                node.TreeView.SelectedNode = node;
        }
        public static void LoadGens(this TreeView treeView, GenomDirectory genomDirectory)
        {
            foreach(GenomItem genomItem in genomDirectory.GenomItems)
                LoadGens(treeView, null, genomItem);
        }
        private static void LoadGens(TreeView treeView, TreeNode node, GenomItem genomItem)
        {
            if (genomItem is Gen)
            {
                ObjectTreeNode<Gen> genNode = ObjectTreeNodeFactory.Generate<Gen>(genomItem as Gen);
                genNode.Name = genomItem.Name;
                genNode.Text = genomItem.Name;
                genNode.ImageKey = ListViewIndexes.Gen;
                genNode.SelectedImageKey = ListViewIndexes.Gen_Selected;
                if (node != null)
                    node.Nodes.Add(genNode);
                else
                    treeView.Nodes.Add(genNode);
            }
            else if (genomItem is Locus)
            {
                Locus locusItem = genomItem as Locus;
                ObjectTreeNode<Locus> locusNode = ObjectTreeNodeFactory.Generate<Locus>(locusItem);
                locusNode.Name = locusItem.Name;
                locusNode.Text = locusItem.Name;
                locusNode.ImageKey = ListViewIndexes.Locus;
                locusNode.SelectedImageKey = ListViewIndexes.Locus_Selected;
                foreach (Gen genItem in locusItem.Gens)
                {
                    ObjectTreeNode<Gen> genNode = ObjectTreeNodeFactory.Generate<Gen>(genItem);
                    genNode.Name = genItem.Name;
                    genNode.Text = genItem.Name;

                    genNode.ImageKey = ListViewIndexes.Gen;
                    genNode.SelectedImageKey = ListViewIndexes.Gen;
                    locusNode.Nodes.Add(genNode);
                }
                if (node != null)
                    node.Nodes.Add(locusNode);
                else
                    treeView.Nodes.Add(locusNode);
            }
            else if (genomItem is GenomDirectory)
            {
                GenomDirectory directoryItem = genomItem as GenomDirectory;
                if (!directoryItem.IsSuperRoot)
                {
                    ObjectTreeNode<GenomDirectory> directoryNode = ObjectTreeNodeFactory.Generate<GenomDirectory>(directoryItem);
                    directoryNode.Name = genomItem.Name;
                    directoryNode.Text = genomItem.Name;
                    directoryNode.ImageKey = ListViewIndexes.GenomDirectory;
                    directoryNode.SelectedImageKey = ListViewIndexes.GenomDirectory_Selected;
                    if (node != null)
                        node.Nodes.Add(directoryNode);
                    else
                        treeView.Nodes.Add(directoryNode);
                    foreach (GenomItem genItem in directoryItem.GenomItems)
                        LoadGens(treeView, directoryNode, genItem);
                }
                else
                {
                    foreach (GenomItem genItem in directoryItem.GenomItems)
                        LoadGens(treeView, null, genItem);
                }
            }
        }
        public static void LoadCharacters(this TreeView treeView, CharacterDirectory characterDirectory)
        {
            LoadCharacters(treeView, characterDirectory, true);
        }
        public static void LoadCharacters(this TreeView treeView, CharacterDirectory characterDirectory, bool AddEmpty)
        {
            foreach (CharacterItem characterItem in characterDirectory.Characters)
                LoadCharacters(treeView, null, characterItem, AddEmpty);
        }
        public static void LoadCharacters(TreeView treeView, TreeNode node, CharacterItem characterItem)
        {
            LoadCharacters(treeView, node, characterItem, false);
        }
        public static void LoadCharacters(TreeView treeView, TreeNode node, CharacterItem characterItem, bool AddEmpty)
        {
            if (characterItem is Character)
            {
                ObjectTreeNode<Character> characterNode = ObjectTreeNodeFactory.Generate<Character>(characterItem as Character);
                characterNode.Name = characterItem.Name;
                characterNode.Text = characterItem.Name;
                characterNode.ImageKey = ListViewIndexes.Character;
                characterNode.SelectedImageKey = ListViewIndexes.Character_Selected;
                if (node != null)
                    node.Nodes.Add(characterNode);
                else
                    treeView.Nodes.Add(characterNode);
            }
            else if (characterItem is CharacterDirectory)
            {
                CharacterDirectory directoryItem = characterItem as CharacterDirectory;
                ObjectTreeNode<CharacterDirectory> directoryNode = ObjectTreeNodeFactory.Generate<CharacterDirectory>(directoryItem);
                directoryNode.Name = directoryItem.Name;
                directoryNode.Text = directoryItem.Name;
                directoryNode.ImageKey = ListViewIndexes.GenomDirectory;
                directoryNode.SelectedImageKey = ListViewIndexes.GenomDirectory_Selected;
                if (AddEmpty || directoryItem.Characters.Count > 0)
                {
                    if (node != null)
                        node.Nodes.Add(directoryNode);
                    else
                        treeView.Nodes.Add(directoryNode);
                }
                foreach (CharacterItem charItem in directoryItem.Characters)
                    LoadCharacters(treeView, directoryNode, charItem);
            }
        }
    }
}
